Add TAL-Reverb-II plugin to test
[juce-lv2.git] / juce / source / extras / the jucer / src / model / paintelements / jucer_ColouredElement.cpp
blob7c084b59d29e0a15cf95f7cbac7404d45e206546
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../jucer_Headers.h"
27 #include "jucer_ColouredElement.h"
28 #include "jucer_GradientPointComponent.h"
29 #include "../../properties/jucer_PositionPropertyBase.h"
30 #include "../../properties/jucer_ColourPropertyComponent.h"
31 #include "jucer_PaintElementUndoableAction.h"
32 #include "jucer_PaintElementPath.h"
33 #include "jucer_ImageResourceProperty.h"
36 //==============================================================================
37 class ElementFillModeProperty : public ChoicePropertyComponent,
38 private ChangeListener
40 public:
41 ElementFillModeProperty (ColouredElement* const owner_, const bool isForStroke_)
42 : ChoicePropertyComponent ("fill mode"),
43 owner (owner_),
44 isForStroke (isForStroke_)
46 choices.add ("Solid Colour");
47 choices.add ("Linear Gradient");
48 choices.add ("Radial Gradient");
49 choices.add ("Image Brush");
51 owner->getDocument()->addChangeListener (this);
54 ~ElementFillModeProperty()
56 owner->getDocument()->removeChangeListener (this);
59 void setIndex (int newIndex)
61 JucerFillType fill (isForStroke ? owner->getStrokeType().fill
62 : owner->getFillType());
64 switch (newIndex)
66 case 0:
67 fill.mode = JucerFillType::solidColour;
68 break;
69 case 1:
70 fill.mode = JucerFillType::linearGradient;
71 break;
72 case 2:
73 fill.mode = JucerFillType::radialGradient;
74 break;
75 case 3:
76 fill.mode = JucerFillType::imageBrush;
77 break;
79 default:
80 jassertfalse
81 break;
84 if (! isForStroke)
85 owner->setFillType (fill, true);
86 else
87 owner->setStrokeFill (fill, true);
90 int getIndex() const
92 switch (isForStroke ? owner->getStrokeType().fill.mode
93 : owner->getFillType().mode)
95 case JucerFillType::solidColour:
96 return 0;
97 case JucerFillType::linearGradient:
98 return 1;
99 case JucerFillType::radialGradient:
100 return 2;
101 case JucerFillType::imageBrush:
102 return 3;
103 default:
104 jassertfalse
105 break;
108 return 0;
111 void changeListenerCallback (ChangeBroadcaster*)
113 refresh();
116 private:
117 ColouredElement* const owner;
118 const bool isForStroke;
121 //==============================================================================
122 class ElementFillColourProperty : public ColourPropertyComponent,
123 private ChangeListener
125 public:
126 enum ColourType
128 solidColour,
129 gradientColour1,
130 gradientColour2
133 ElementFillColourProperty (const String& name,
134 ColouredElement* const owner_,
135 const ColourType type_,
136 const bool isForStroke_)
137 : ColourPropertyComponent (name, false),
138 owner (owner_),
139 type (type_),
140 isForStroke (isForStroke_)
142 owner->getDocument()->addChangeListener (this);
145 ~ElementFillColourProperty()
147 owner->getDocument()->removeChangeListener (this);
150 void setColour (const Colour& newColour)
152 owner->getDocument()->getUndoManager().undoCurrentTransactionOnly();
154 JucerFillType fill (isForStroke ? owner->getStrokeType().fill
155 : owner->getFillType());
157 switch (type)
159 case solidColour:
160 fill.colour = newColour;
161 break;
163 case gradientColour1:
164 fill.gradCol1 = newColour;
165 break;
167 case gradientColour2:
168 fill.gradCol2 = newColour;
169 break;
171 default:
172 jassertfalse
173 break;
176 if (! isForStroke)
177 owner->setFillType (fill, true);
178 else
179 owner->setStrokeFill (fill, true);
182 const Colour getColour() const
184 const JucerFillType fill (isForStroke ? owner->getStrokeType().fill
185 : owner->getFillType());
187 switch (type)
189 case solidColour:
190 return fill.colour;
191 break;
193 case gradientColour1:
194 return fill.gradCol1;
195 break;
197 case gradientColour2:
198 return fill.gradCol2;
199 break;
201 default:
202 jassertfalse
203 break;
206 return Colours::black;
209 void resetToDefault()
211 jassertfalse // option shouldn't be visible
214 void changeListenerCallback (ChangeBroadcaster*)
216 refresh();
219 private:
220 ColouredElement* const owner;
221 const ColourType type;
222 const bool isForStroke;
225 //==============================================================================
226 class ElementFillPositionProperty : public PositionPropertyBase
228 public:
229 ElementFillPositionProperty (ColouredElement* const owner_,
230 const String& name,
231 ComponentPositionDimension dimension_,
232 const bool isStart_,
233 const bool isForStroke_)
234 : PositionPropertyBase (owner_, name, dimension_, false, false,
235 owner_->getDocument()->getComponentLayout()),
236 owner (owner_),
237 isStart (isStart_),
238 isForStroke (isForStroke_)
240 owner->getDocument()->addChangeListener (this);
243 ~ElementFillPositionProperty()
245 owner->getDocument()->removeChangeListener (this);
248 //==============================================================================
249 void setPosition (const RelativePositionedRectangle& newPos)
251 JucerFillType fill (isForStroke ? owner->getStrokeType().fill
252 : owner->getFillType());
254 if (isStart)
255 fill.gradPos1 = newPos;
256 else
257 fill.gradPos2 = newPos;
259 if (! isForStroke)
260 owner->setFillType (fill, true);
261 else
262 owner->setStrokeFill (fill, true);
265 const RelativePositionedRectangle getPosition() const
267 const JucerFillType fill (isForStroke ? owner->getStrokeType().fill
268 : owner->getFillType());
270 return isStart ? fill.gradPos1
271 : fill.gradPos2;
274 private:
275 ColouredElement* const owner;
276 const bool isStart, isForStroke;
279 //==============================================================================
280 class EnableStrokeProperty : public BooleanPropertyComponent,
281 public ChangeListener
283 public:
284 EnableStrokeProperty (ColouredElement* const owner_)
285 : BooleanPropertyComponent ("outline", "Outline enabled", "No outline"),
286 owner (owner_)
288 owner->getDocument()->addChangeListener (this);
291 ~EnableStrokeProperty()
293 owner->getDocument()->removeChangeListener (this);
296 //==============================================================================
297 void setState (bool newState) { owner->enableStroke (newState, true); }
298 bool getState() const { return owner->isStrokeEnabled(); }
300 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
302 private:
303 ColouredElement* const owner;
306 //==============================================================================
307 class StrokeThicknessProperty : public SliderPropertyComponent,
308 public ChangeListener
310 public:
311 StrokeThicknessProperty (ColouredElement* const owner_)
312 : SliderPropertyComponent ("outline thickness", 0.1, 200.0, 0.1, 0.3),
313 owner (owner_)
315 owner->getDocument()->addChangeListener (this);
318 ~StrokeThicknessProperty()
320 owner->getDocument()->removeChangeListener (this);
323 void setValue (double newValue)
325 owner->getDocument()->getUndoManager().undoCurrentTransactionOnly();
327 owner->setStrokeType (PathStrokeType ((float) newValue,
328 owner->getStrokeType().stroke.getJointStyle(),
329 owner->getStrokeType().stroke.getEndStyle()),
330 true);
333 double getValue() const { return owner->getStrokeType().stroke.getStrokeThickness(); }
335 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
337 private:
338 ColouredElement* const owner;
341 //==============================================================================
342 class StrokeJointProperty : public ChoicePropertyComponent,
343 public ChangeListener
345 public:
346 StrokeJointProperty (ColouredElement* const owner_)
347 : ChoicePropertyComponent ("joint style"),
348 owner (owner_)
350 choices.add ("mitered");
351 choices.add ("curved");
352 choices.add ("beveled");
354 owner->getDocument()->addChangeListener (this);
357 ~StrokeJointProperty()
359 owner->getDocument()->removeChangeListener (this);
362 void setIndex (int newIndex)
364 const PathStrokeType::JointStyle joints[] = { PathStrokeType::mitered,
365 PathStrokeType::curved,
366 PathStrokeType::beveled };
368 jassert (newIndex >= 0 && newIndex < 3);
370 owner->setStrokeType (PathStrokeType (owner->getStrokeType().stroke.getStrokeThickness(),
371 joints [newIndex],
372 owner->getStrokeType().stroke.getEndStyle()),
373 true);
376 int getIndex() const
378 switch (owner->getStrokeType().stroke.getJointStyle())
380 case PathStrokeType::mitered:
381 return 0;
382 case PathStrokeType::curved:
383 return 1;
384 case PathStrokeType::beveled:
385 return 2;
386 default:
387 jassertfalse
388 break;
391 return 0;
394 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
396 private:
397 ColouredElement* const owner;
400 //==============================================================================
401 class StrokeEndCapProperty : public ChoicePropertyComponent,
402 public ChangeListener
404 public:
405 StrokeEndCapProperty (ColouredElement* const owner_)
406 : ChoicePropertyComponent ("end-cap style"),
407 owner (owner_)
409 choices.add ("butt");
410 choices.add ("square");
411 choices.add ("round");
413 owner->getDocument()->addChangeListener (this);
416 ~StrokeEndCapProperty()
418 owner->getDocument()->removeChangeListener (this);
421 void setIndex (int newIndex)
423 const PathStrokeType::EndCapStyle ends[] = { PathStrokeType::butt,
424 PathStrokeType::square,
425 PathStrokeType::rounded };
427 jassert (newIndex >= 0 && newIndex < 3);
429 owner->setStrokeType (PathStrokeType (owner->getStrokeType().stroke.getStrokeThickness(),
430 owner->getStrokeType().stroke.getJointStyle(),
431 ends [newIndex]),
432 true);
435 int getIndex() const
437 switch (owner->getStrokeType().stroke.getEndStyle())
439 case PathStrokeType::butt:
440 return 0;
441 case PathStrokeType::square:
442 return 1;
443 case PathStrokeType::rounded:
444 return 2;
445 default:
446 jassertfalse
447 break;
450 return 0;
453 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
455 private:
456 ColouredElement* const owner;
459 //==============================================================================
460 class ImageBrushResourceProperty : public ImageResourceProperty <ColouredElement>
462 public:
463 ImageBrushResourceProperty (ColouredElement* const element_, const bool isForStroke_)
464 : ImageResourceProperty <ColouredElement> (element_, isForStroke_ ? "stroke image"
465 : "fill image"),
466 isForStroke (isForStroke_)
470 //==============================================================================
471 void setResource (const String& newName)
473 if (isForStroke)
475 JucerFillType type (element->getStrokeType().fill);
476 type.imageResourceName = newName;
478 element->setStrokeFill (type, true);
480 else
482 JucerFillType type (element->getFillType());
483 type.imageResourceName = newName;
485 element->setFillType (type, true);
489 const String getResource() const
491 if (isForStroke)
492 return element->getStrokeType().fill.imageResourceName;
493 else
494 return element->getFillType().imageResourceName;
497 private:
498 bool isForStroke;
501 //==============================================================================
502 class ImageBrushPositionProperty : public PositionPropertyBase
504 public:
505 ImageBrushPositionProperty (ColouredElement* const owner_,
506 const String& name,
507 ComponentPositionDimension dimension_,
508 const bool isForStroke_)
509 : PositionPropertyBase (owner_, name, dimension_, false, false,
510 owner_->getDocument()->getComponentLayout()),
511 owner (owner_),
512 isForStroke (isForStroke_)
514 owner->getDocument()->addChangeListener (this);
517 ~ImageBrushPositionProperty()
519 owner->getDocument()->removeChangeListener (this);
522 void setPosition (const RelativePositionedRectangle& newPos)
524 if (isForStroke)
526 JucerFillType type (owner->getStrokeType().fill);
527 type.imageAnchor = newPos;
528 owner->setStrokeFill (type, true);
530 else
532 JucerFillType type (owner->getFillType());
533 type.imageAnchor = newPos;
534 owner->setFillType (type, true);
538 const RelativePositionedRectangle getPosition() const
540 if (isForStroke)
541 return owner->getStrokeType().fill.imageAnchor;
542 else
543 return owner->getFillType().imageAnchor;
546 private:
547 ColouredElement* const owner;
548 const bool isForStroke;
551 //==============================================================================
552 class ImageBrushOpacityProperty : public SliderPropertyComponent,
553 private ChangeListener
555 public:
556 ImageBrushOpacityProperty (ColouredElement* const element_, const bool isForStroke_)
557 : SliderPropertyComponent ("opacity", 0.0, 1.0, 0.001),
558 element (element_),
559 isForStroke (isForStroke_)
561 element->getDocument()->addChangeListener (this);
564 ~ImageBrushOpacityProperty()
566 element->getDocument()->removeChangeListener (this);
569 void setValue (double newValue)
571 element->getDocument()->getUndoManager().undoCurrentTransactionOnly();
573 if (isForStroke)
575 JucerFillType type (element->getStrokeType().fill);
576 type.imageOpacity = newValue;
578 element->setStrokeFill (type, true);
580 else
582 JucerFillType type (element->getFillType());
583 type.imageOpacity = newValue;
585 element->setFillType (type, true);
589 double getValue() const
591 if (isForStroke)
592 return element->getStrokeType().fill.imageOpacity;
593 else
594 return element->getFillType().imageOpacity;
597 void changeListenerCallback (ChangeBroadcaster*)
599 refresh();
602 private:
603 ColouredElement* const element;
604 bool isForStroke;
608 //==============================================================================
609 ColouredElement::ColouredElement (PaintRoutine* owner_,
610 const String& name,
611 const bool showOutline_,
612 const bool showJointAndEnd_)
613 : PaintElement (owner_, name),
614 isStrokePresent (false),
615 showOutline (showOutline_),
616 showJointAndEnd (showJointAndEnd_)
620 ColouredElement::~ColouredElement()
624 //==============================================================================
625 void ColouredElement::getEditableProperties (Array <PropertyComponent*>& properties)
627 PaintElement::getEditableProperties (properties);
628 getColourSpecificProperties (properties);
631 void ColouredElement::getColourSpecificProperties (Array <PropertyComponent*>& properties)
633 properties.add (new ElementFillModeProperty (this, false));
635 switch (getFillType().mode)
637 case JucerFillType::solidColour:
638 properties.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, false));
639 break;
641 case JucerFillType::linearGradient:
642 case JucerFillType::radialGradient:
643 properties.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, false));
644 properties.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, false));
645 properties.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, false));
646 properties.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, false));
647 properties.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, false));
648 properties.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, false));
649 break;
651 case JucerFillType::imageBrush:
652 properties.add (new ImageBrushResourceProperty (this, false));
653 properties.add (new ImageBrushPositionProperty (this, "anchor x", PositionPropertyBase::componentX, false));
654 properties.add (new ImageBrushPositionProperty (this, "anchor y", PositionPropertyBase::componentY, false));
655 properties.add (new ImageBrushOpacityProperty (this, false));
656 break;
658 default:
659 jassertfalse
660 break;
663 if (showOutline)
665 properties.add (new EnableStrokeProperty (this));
667 if (isStrokePresent)
669 properties.add (new StrokeThicknessProperty (this));
671 if (showJointAndEnd)
673 properties.add (new StrokeJointProperty (this));
674 properties.add (new StrokeEndCapProperty (this));
677 properties.add (new ElementFillModeProperty (this, true));
679 switch (getStrokeType().fill.mode)
681 case JucerFillType::solidColour:
682 properties.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, true));
683 break;
685 case JucerFillType::linearGradient:
686 case JucerFillType::radialGradient:
687 properties.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, true));
688 properties.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, true));
689 properties.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, true));
690 properties.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, true));
691 properties.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, true));
692 properties.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, true));
693 break;
695 case JucerFillType::imageBrush:
696 properties.add (new ImageBrushResourceProperty (this, true));
697 properties.add (new ImageBrushPositionProperty (this, "stroke anchor x", PositionPropertyBase::componentX, true));
698 properties.add (new ImageBrushPositionProperty (this, "stroke anchor y", PositionPropertyBase::componentY, true));
699 properties.add (new ImageBrushOpacityProperty (this, true));
700 break;
702 default:
703 jassertfalse
704 break;
710 //==============================================================================
711 const JucerFillType& ColouredElement::getFillType() throw()
713 return fillType;
716 class FillTypeChangeAction : public PaintElementUndoableAction <ColouredElement>
718 public:
719 FillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_)
720 : PaintElementUndoableAction <ColouredElement> (element),
721 newState (newState_)
723 oldState = element->getFillType();
726 bool perform()
728 showCorrectTab();
729 getElement()->setFillType (newState, false);
730 return true;
733 bool undo()
735 showCorrectTab();
736 getElement()->setFillType (oldState, false);
737 return true;
740 private:
741 JucerFillType newState, oldState;
744 void ColouredElement::setFillType (const JucerFillType& newType, const bool undoable)
746 if (fillType != newType)
748 if (undoable)
750 perform (new FillTypeChangeAction (this, newType),
751 "Change fill type");
753 else
755 repaint();
757 if (fillType.mode != newType.mode)
759 owner->getSelectedElements().changed();
760 siblingComponentsChanged();
763 fillType = newType;
764 changed();
769 //==============================================================================
770 bool ColouredElement::isStrokeEnabled() const throw()
772 return isStrokePresent && showOutline;
775 class StrokeEnableChangeAction : public PaintElementUndoableAction <ColouredElement>
777 public:
778 StrokeEnableChangeAction (ColouredElement* const element, const bool newState_)
779 : PaintElementUndoableAction <ColouredElement> (element),
780 newState (newState_)
782 oldState = element->isStrokeEnabled();
785 bool perform()
787 showCorrectTab();
788 getElement()->enableStroke (newState, false);
789 return true;
792 bool undo()
794 showCorrectTab();
795 getElement()->enableStroke (oldState, false);
796 return true;
799 private:
800 bool newState, oldState;
803 void ColouredElement::enableStroke (bool enable, const bool undoable)
805 enable = enable && showOutline;
807 if (isStrokePresent != enable)
809 if (undoable)
811 perform (new StrokeEnableChangeAction (this, enable),
812 "Change stroke mode");
814 else
816 repaint();
817 isStrokePresent = enable;
819 siblingComponentsChanged();
820 owner->changed();
821 owner->getSelectedElements().changed();
826 //==============================================================================
827 const StrokeType& ColouredElement::getStrokeType() throw()
829 return strokeType;
832 class StrokeTypeChangeAction : public PaintElementUndoableAction <ColouredElement>
834 public:
835 StrokeTypeChangeAction (ColouredElement* const element, const PathStrokeType& newState_)
836 : PaintElementUndoableAction <ColouredElement> (element),
837 newState (newState_),
838 oldState (element->getStrokeType().stroke)
842 bool perform()
844 showCorrectTab();
845 getElement()->setStrokeType (newState, false);
846 return true;
849 bool undo()
851 showCorrectTab();
852 getElement()->setStrokeType (oldState, false);
853 return true;
856 private:
857 PathStrokeType newState, oldState;
860 void ColouredElement::setStrokeType (const PathStrokeType& newType, const bool undoable)
862 if (strokeType.stroke != newType)
864 if (undoable)
866 perform (new StrokeTypeChangeAction (this, newType),
867 "Change stroke type");
869 else
871 repaint();
872 strokeType.stroke = newType;
873 changed();
878 class StrokeFillTypeChangeAction : public PaintElementUndoableAction <ColouredElement>
880 public:
881 StrokeFillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_)
882 : PaintElementUndoableAction <ColouredElement> (element),
883 newState (newState_)
885 oldState = element->getStrokeType().fill;
888 bool perform()
890 showCorrectTab();
891 getElement()->setStrokeFill (newState, false);
892 return true;
895 bool undo()
897 showCorrectTab();
898 getElement()->setStrokeFill (oldState, false);
899 return true;
902 private:
903 JucerFillType newState, oldState;
906 void ColouredElement::setStrokeFill (const JucerFillType& newType, const bool undoable)
908 if (strokeType.fill != newType)
910 if (undoable)
912 perform (new StrokeFillTypeChangeAction (this, newType),
913 "Change stroke fill type");
915 else
917 repaint();
919 if (strokeType.fill.mode != newType.mode)
921 siblingComponentsChanged();
922 owner->getSelectedElements().changed();
925 strokeType.fill = newType;
926 changed();
931 //==============================================================================
932 void ColouredElement::createSiblingComponents()
934 GradientPointComponent* g1 = new GradientPointComponent (this, false, true);
935 siblingComponents.add (g1);
937 GradientPointComponent* g2 = new GradientPointComponent (this, false, false);
938 siblingComponents.add (g2);
940 getParentComponent()->addAndMakeVisible (g1);
941 getParentComponent()->addAndMakeVisible (g2);
943 g1->updatePosition();
944 g2->updatePosition();
946 if (isStrokePresent && showOutline)
948 GradientPointComponent* g1 = new GradientPointComponent (this, true, true);
949 siblingComponents.add (g1);
951 GradientPointComponent* g2 = new GradientPointComponent (this, true, false);
952 siblingComponents.add (g2);
954 getParentComponent()->addAndMakeVisible (g1);
955 getParentComponent()->addAndMakeVisible (g2);
957 g1->updatePosition();
958 g2->updatePosition();
962 const Rectangle<int> ColouredElement::getCurrentBounds (const Rectangle<int>& parentArea) const
964 int border = 0;
966 if (isStrokePresent)
967 border = (int) strokeType.stroke.getStrokeThickness() / 2 + 1;
969 return position.getRectangle (parentArea, getDocument()->getComponentLayout())
970 .expanded (border, border);
973 void ColouredElement::setCurrentBounds (const Rectangle<int>& newBounds,
974 const Rectangle<int>& parentArea,
975 const bool undoable)
977 Rectangle<int> r (newBounds);
979 if (isStrokePresent)
981 const int border = (int) strokeType.stroke.getStrokeThickness() / 2 + 1;
982 r = r.expanded (-border, -border);
984 r.setSize (jmax (1, r.getWidth()), jmax (1, r.getHeight()));
987 RelativePositionedRectangle pr (position);
988 pr.updateFrom (r.getX() - parentArea.getX(),
989 r.getY() - parentArea.getY(),
990 r.getWidth(), r.getHeight(),
991 Rectangle<int> (0, 0, parentArea.getWidth(), parentArea.getHeight()),
992 getDocument()->getComponentLayout());
993 setPosition (pr, undoable);
995 updateBounds (parentArea);
998 //==============================================================================
999 void ColouredElement::addColourAttributes (XmlElement* const e) const
1001 e->setAttribute ("fill", fillType.toString());
1002 e->setAttribute ("hasStroke", isStrokePresent);
1004 if (isStrokePresent && showOutline)
1006 e->setAttribute ("stroke", strokeType.toString());
1007 e->setAttribute ("strokeColour", strokeType.fill.toString());
1011 bool ColouredElement::loadColourAttributes (const XmlElement& xml)
1013 fillType.restoreFromString (xml.getStringAttribute ("fill", String::empty));
1015 isStrokePresent = showOutline && xml.getBoolAttribute ("hasStroke", false);
1017 strokeType.restoreFromString (xml.getStringAttribute ("stroke", String::empty));
1018 strokeType.fill.restoreFromString (xml.getStringAttribute ("strokeColour", String::empty));
1020 return true;
1023 //==============================================================================
1024 void ColouredElement::convertToNewPathElement (const Path& path)
1026 if (! path.isEmpty())
1028 PaintElementPath* newElement = new PaintElementPath (getOwner());
1029 newElement->setToPath (path);
1030 newElement->setFillType (fillType, false);
1031 newElement->enableStroke (isStrokeEnabled(), false);
1032 newElement->setStrokeType (getStrokeType().stroke, false);
1033 newElement->setStrokeFill (getStrokeType().fill, false);
1035 XmlElement* xml = newElement->createXml();
1036 delete newElement;
1038 PaintElement* e = getOwner()->addElementFromXml (*xml, getOwner()->indexOfElement (this), true);
1039 delete xml;
1041 getOwner()->getSelectedElements().selectOnly (e);
1042 getOwner()->removeElement (this, true);